package test;

import lucava.metamodel.dot.DotAssociation;
import lucava.metamodel.dot.DotGraph;
import lucava.metamodel.dot.DotNode;
import lucava.metamodel.dot.DotProperty;
import lucava.metamodel.dot.DotSubgraph;
import lucava.metamodel.dot.visitor.DotFileGenerator;
import lucava.util.FileBuffer;
import lucava.util.FileBufferWriter;
import lucava.util.GraphVizGenerator;

/**
 * Classe de test pour la génération d'un fichier DOT depuis un MetaModel DOT.
 */
public class DotGeneratorTester {

	public static void main(String[] args) {

		// digraph Grf {
		// subgraph cluster0{
		// node [label="process #1",color=white];
		// style=filled;
		// color=lightgrey;
		// a0;
		// a1;
		// a2;
		// a3;
		// }
		// subgraph cluster1{
		// node [label="process #2",style=filled];
		// a0 -> a1;
		// a1 -> a2;
		// a2 -> a3;
		// a3 -> a0;
		// b0 -> b1;
		// b1 -> b2;
		// b2 -> b3;
		// b0 [shape=record,label="{ b |{c|<here> d|e}| f}"];
		// b1;
		// b2;
		// b3;
		// }
		// Start -> a0;
		// Start -> b0;
		// a3 -> End;
		// b3 -> End;
		// a1 -> b3 [ltail=cluster0,lhead=cluster1,tailport=se];
		// b2 -> a3;
		// Start [shape=Mdiamond];
		// End [arrowhead=Msquare];
		// }

		DotGraph graph = new DotGraph();
		graph.setName("Grf");

		DotSubgraph subgraph1 = new DotSubgraph();
		subgraph1.setName("cluster0");

		DotProperty labelProp = new DotProperty();
		labelProp.setPropertyValue("label=\"process #1\"");
		subgraph1.getGraphProperties().add(labelProp);

		DotProperty prop1 = new DotProperty();
		prop1.setPropertyValue("color=white");
		subgraph1.getNodeProperties().add(prop1);

		DotProperty gProp1 = new DotProperty();
		gProp1.setPropertyValue("style=filled");
		subgraph1.getGraphProperties().add(gProp1);

		DotProperty gProp2 = new DotProperty();
		gProp2.setPropertyValue("color=lightgrey");
		subgraph1.getGraphProperties().add(gProp2);

		DotSubgraph subgraph2 = new DotSubgraph();
		subgraph2.setName("cluster1");

		DotProperty label2Prop = new DotProperty();
		label2Prop.setPropertyValue("label=\"process #2\"");
		subgraph2.getGraphProperties().add(label2Prop);

		DotProperty prop2 = new DotProperty();
		prop2.setPropertyValue("style=filled");
		subgraph2.getNodeProperties().add(prop2);

		DotNode nodeA0 = new DotNode();
		nodeA0.setName("a0");

		DotNode nodeA1 = new DotNode();
		nodeA1.setName("a1");

		DotNode nodeA2 = new DotNode();
		nodeA2.setName("a2");

		DotNode nodeA3 = new DotNode();
		nodeA3.setName("a3");

		subgraph1.getNodes().add(nodeA0);
		subgraph1.getNodes().add(nodeA1);
		subgraph1.getNodes().add(nodeA2);
		subgraph1.getNodes().add(nodeA3);

		DotAssociation assoA1 = new DotAssociation();
		assoA1.setFromNode(nodeA0);
		assoA1.setToNode(nodeA1);

		DotAssociation assoA2 = new DotAssociation();
		assoA2.setFromNode(nodeA1);
		assoA2.setToNode(nodeA2);

		DotAssociation assoA3 = new DotAssociation();
		assoA3.setFromNode(nodeA2);
		assoA3.setToNode(nodeA3);

		DotAssociation assoA4 = new DotAssociation();
		assoA4.setFromNode(nodeA3);
		assoA4.setToNode(nodeA0);

		subgraph2.getAssociations().add(assoA1);
		subgraph2.getAssociations().add(assoA2);
		subgraph2.getAssociations().add(assoA3);
		subgraph2.getAssociations().add(assoA4);

		DotNode nodeB0 = new DotNode();
		nodeB0.setName("b0");

		DotProperty propB = new DotProperty();
		propB.setPropertyValue("shape=record,label=\"{ b |{c|<here> d|e}| f}\"");
		nodeB0.getNodeProperties().add(propB);

		DotNode nodeB1 = new DotNode();
		nodeB1.setName("b1");

		DotNode nodeB2 = new DotNode();
		nodeB2.setName("b2");

		DotNode nodeB3 = new DotNode();
		nodeB3.setName("b3");

		subgraph2.getNodes().add(nodeB0);
		subgraph2.getNodes().add(nodeB1);
		subgraph2.getNodes().add(nodeB2);
		subgraph2.getNodes().add(nodeB3);

		DotAssociation assoB1 = new DotAssociation();
		assoB1.setFromNode(nodeB0);
		assoB1.setToNode(nodeB1);

		DotAssociation assoB2 = new DotAssociation();
		assoB2.setFromNode(nodeB1);
		assoB2.setToNode(nodeB2);

		DotAssociation assoB3 = new DotAssociation();
		assoB3.setFromNode(nodeB2);
		assoB3.setToNode(nodeB3);

		subgraph2.getAssociations().add(assoB1);
		subgraph2.getAssociations().add(assoB2);
		subgraph2.getAssociations().add(assoB3);

		DotNode nodeStart = new DotNode();
		nodeStart.setName("Start");
		DotProperty propStart = new DotProperty();
		propStart.setPropertyValue("shape=Mdiamond");
		nodeStart.getNodeProperties().add(propStart);

		DotNode nodeEnd = new DotNode();
		nodeEnd.setName("End");
		DotProperty propEnd = new DotProperty();
		propEnd.setPropertyValue("arrowhead=Msquare");
		nodeEnd.getNodeProperties().add(propEnd);

		graph.getNodes().add(nodeStart);
		graph.getNodes().add(nodeEnd);

		DotAssociation assoG1 = new DotAssociation();
		assoG1.setFromNode(nodeStart);
		assoG1.setToNode(nodeA0);

		DotAssociation assoG2 = new DotAssociation();
		assoG2.setFromNode(nodeStart);
		assoG2.setToNode(nodeB0);

		DotAssociation assoG3 = new DotAssociation();
		assoG3.setFromNode(nodeA3);
		assoG3.setToNode(nodeEnd);

		DotAssociation assoG4 = new DotAssociation();
		assoG4.setFromNode(nodeB3);
		assoG4.setToNode(nodeEnd);

		DotAssociation assoG5 = new DotAssociation();
		assoG5.setFromNode(nodeA1);
		assoG5.setToNode(nodeB3);

		DotProperty assocProp1 = new DotProperty();
		assocProp1.setPropertyValue("ltail=cluster0");
		assoG5.getProperties().add(assocProp1);

		DotProperty assocProp2 = new DotProperty();
		assocProp2.setPropertyValue("lhead=cluster1");
		assoG5.getProperties().add(assocProp2);

		DotProperty assocProp3 = new DotProperty();
		assocProp3.setPropertyValue("tailport=se");
		assoG5.getProperties().add(assocProp3);

		DotAssociation assoG6 = new DotAssociation();
		assoG6.setFromNode(nodeB2);
		assoG6.setToNode(nodeA3);

		graph.getAssociations().add(assoG1);
		graph.getAssociations().add(assoG2);
		graph.getAssociations().add(assoG3);
		graph.getAssociations().add(assoG4);
		graph.getAssociations().add(assoG5);
		graph.getAssociations().add(assoG6);

		graph.getSubGraphs().add(subgraph1);
		graph.getSubGraphs().add(subgraph2);

		DotFileGenerator generator = new DotFileGenerator();
		graph.accept(generator);

		FileBuffer generatedDot = generator.getGeneratedFile();
		FileBufferWriter.generateFileFor(generatedDot);

		GraphVizGenerator.generatePNGFromFile(graph.getName() + ".dot","data/test/GeneratedGraph1.png");
	}
}
